import { truthy } from '@gnlab/utils'
import { App, Button } from 'antd'
import formatAssetUrl from '@/desktop/logics/format-asset-url'
import { getAudioInfo } from '@/lib/utils'
import { commonS } from './common-styles'
import { type BaseProps, type CommonProps, propsWithDefaults, useUpload } from './logics'

type AudioProps = BaseProps<string | null> & Pick<CommonProps, 'duration'>

export function UploadAudio(props: AudioProps) {
  const { message } = App.useApp()
  const { cdn, tips, sizeLimit, duration, value = null, onChange } = propsWithDefaults(props)
  const usedSizeLimit = sizeLimit || 50
  const [uploading, upload] = useUpload(cdn)
  const inputRef = useRef<HTMLInputElement>(null)

  const inputOnChange = useCallback(
    async (e: React.ChangeEvent<HTMLInputElement>) => {
      const file = e.target.files?.[0] ?? null
      e.target.value = ''

      if (file) {
        const size = file.size
        if (size > 1024 * 1024 * usedSizeLimit) {
          void message.warning(`音频文件不能大于${usedSizeLimit}M`)
          return
        }

        if (duration) {
          const { duration: audioDuration } = await getAudioInfo(file)
          if (duration && audioDuration > duration) {
            void message.warning(`音频长度不能超过${duration}s`)
            return
          }
        }

        const uploaded = await upload(file)
        if (uploaded) onChange(uploaded.url)
      }
    },
    [usedSizeLimit, duration, upload, onChange, message],
  )

  return <div css={commonS.upload}>
    {truthy(value) ? (
      <audio css={s.audio} controls src={formatAssetUrl(value)}>
        当前浏览器无法播放此音频
      </audio>
    ) : null}

    <div css={s.actions}>
      <Button loading={uploading} onClick={() => inputRef.current?.click()}>
        {truthy(value) ? '重新上传' : '上传音频'}
      </Button>
      {truthy(value) ? (
        <Button loading={uploading} danger onClick={() => onChange(null)}>
          删除
        </Button>
      ) : null}
    </div>

    <div css={commonS.uploadTips}>{truthy(tips) ? tips : `音频文件不得超过${usedSizeLimit}M`}</div>
    <input type="file" accept=".aac,.mp3" ref={inputRef} onChange={inputOnChange} />
  </div>
}

const s = {
  audio: css`
    display: block;
    margin-bottom: 12px;
  `,
  actions: css`
    button:not(:last-child) {
      margin-right: 1.5em;
    }
  `,
}
